package com.apache.client;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apache.api.vo.ParamsVo;
import com.apache.cache.service.impl.LoadCacheFactory;
import com.apache.cache.util.Validator;
import com.apache.info.util.MessageUtil;
import com.apache.tools.StrUtil;
import com.apache.uct.common.ToolsUtil;

import java.util.HashMap;
import java.util.Map;

/**
 * @description: IUS请求参数解析
 * @author: Hou Dayu
 * @date: Created in 2020/4/21
 */
public class IUSRequestParams {

    /**
     * IUS参数解析
     * @param params IUS参数配置信息
     */
    public static Map<String,Object> analyzeParams(Map params){
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("ParamType", "json");
        String datasource = String.valueOf(params.get("sysName"));
        resultMap.put("datasource", datasource);//数据源
        //<input type="text" name="modelTypes" value="i_pro,i_pub" />
        String modelType = String.valueOf(params.get("modelTypes"));//待操作表
        //<input type="text" name="pub.proId" value="[pro.proId]" />
        //<input type="text" name="pub.proName" value="[pro.proName]" />
        //pub.proId=[pro.proId],pub.proName=[pro.proName]
        String relation = String.valueOf(params.get("relation"));//关联关系
        //<input type="text" name="sqlKeyId" value="0001" />
        //<input type="text" name="beforMethodKey" value="0001" />
        String rules = String.valueOf(params.get("rulesName"));//执行插件

        String resultSetCacheKey = String.valueOf(params.get("cacheKey"));//(是否加缓存)批定的缓存KEy
        if(Validator.isNotNull(resultSetCacheKey)){//批定KEY则将结果结放到缓存
            resultMap.put("resultSetCacheKey", resultSetCacheKey);
        }

        String resultColumn = String.valueOf(params.get("resultColumn"));//返回列
        if (ToolsUtil.isNotNull(resultColumn)) {
            resultMap.put("result_column", resultColumn);
        }
        String checkColumn = String.valueOf(params.get("checkColumn"));
        if (ToolsUtil.isNotNull(checkColumn)) {
            resultMap.put("checkColumn", checkColumn);
        }

        if (ToolsUtil.isNotNull(modelType)) {
            resultMap.put("modelTypes", modelType);
            if (ToolsUtil.isNotNull(relation)) {//以下处理关联关系
                if(relation.startsWith("[")){
                    JSONArray jsons = JSON.parseArray(relation);
                    StringBuilder sb = new StringBuilder();
                    for(int i=0;i<jsons.size();i++){
                        sb.append(buildParams(jsons.getJSONObject(i),datasource,modelType,resultMap,new HashMap()));
                    }
                   if(sb.length() >1){
                       resultMap.put("ius_sql_where",sb.toString());
                   }
                }  else {
                    String str[] = relation.split(",");
                    for (int i = 0; i < str.length; i++) {
                        String ps[] = str[i].split("=");
                        resultMap.put(ps[0], ps[1]);
                    }
                    if (!modelType.startsWith("s_")) {
                        //relation= pub.proId=[pro.proId],pro.w_proId=[pro.proId],如果relation中存在pro.w_proId=[pro.proId],转为pro.proId=[pro.proId]
                        relation = relation.replaceAll("w_", "");
                        //<input name="exe_rules" value="pub.proId:[pro.proId],pub.proName:[pro.proName]"/>
                        resultMap.put("exe_rules", relation.replace("=", ":"));
                    }
                }
            }
        }
        if (ToolsUtil.isNotNull(rules)) {//以下处理执行插件
            resultMap.put("sqlKeyId", rules);
            String evelName = StrUtil.doNull(String.valueOf(params.get("evelName")),"beforMethodKey");//方法拦截方式,前拦或后拦
            resultMap.put(evelName, rules);
        } else {
            resultMap.put("sqlKeyId", "sqlKeyId");
        }
        //返回值名称,T:实体.属性名 或 F:属性名
        if ("T".equalsIgnoreCase(String.valueOf(params.get("resultName")))) {
            resultMap.put("_resultType", "T");
        }
        return resultMap;
    }

    /**
     * IUS参数解析
     * @param params IUS参数配置信息
     */
    public static Map<String,Object> analyzeParams(Map params,Map reqParams){
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("ParamType", "json");
        String datasource = String.valueOf(params.get("sysName"));
        resultMap.put("datasource", datasource);//数据源
        //<input type="text" name="modelTypes" value="i_pro,i_pub" />
        String modelType = String.valueOf(params.get("modelTypes"));//待操作表
        //<input type="text" name="pub.proId" value="[pro.proId]" />
        //<input type="text" name="pub.proName" value="[pro.proName]" />
        //pub.proId=[pro.proId],pub.proName=[pro.proName]
        String relation = String.valueOf(params.get("relation"));//关联关系
        //<input type="text" name="sqlKeyId" value="0001" />
        //<input type="text" name="beforMethodKey" value="0001" />
        String rules = String.valueOf(params.get("rulesName"));//执行插件

        String resultSetCacheKey = String.valueOf(params.get("cacheKey"));//(是否加缓存)批定的缓存KEy
        if(Validator.isNotNull(resultSetCacheKey)){//批定KEY则将结果结放到缓存
            resultMap.put("resultSetCacheKey", resultSetCacheKey);
        }

        String resultColumn = String.valueOf(params.get("resultColumn"));//返回列
        if (ToolsUtil.isNotNull(resultColumn)) {
            resultMap.put("result_column", resultColumn);
        }
        String checkColumn = String.valueOf(params.get("checkColumn"));
        if (ToolsUtil.isNotNull(checkColumn)) {
            resultMap.put("checkColumn", checkColumn);
        }

        if (ToolsUtil.isNotNull(modelType)) {
            resultMap.put("modelTypes", modelType);
            if (ToolsUtil.isNotNull(relation)) {//以下处理关联关系
                if(relation.startsWith("[")){
                    JSONArray jsons = JSON.parseArray(relation);
                    StringBuilder sb = new StringBuilder();
                    for(int i=0;i<jsons.size();i++){
                        sb.append(buildParams(jsons.getJSONObject(i),datasource,modelType,resultMap,reqParams));
                    }
                    if(sb.length() >1){
                        resultMap.put("ius_sql_where",sb.toString());
                    }
                }  else {
                    String str[] = relation.split(",");
                    for (int i = 0; i < str.length; i++) {
                        String ps[] = str[i].split("=");
                        resultMap.put(ps[0], ps[1]);
                    }
                    if (!modelType.startsWith("s_")) {
                        //relation= pub.proId=[pro.proId],pro.w_proId=[pro.proId],如果relation中存在pro.w_proId=[pro.proId],转为pro.proId=[pro.proId]
                        relation = relation.replaceAll("w_", "");
                        //<input name="exe_rules" value="pub.proId:[pro.proId],pub.proName:[pro.proName]"/>
                        resultMap.put("exe_rules", relation.replace("=", ":"));
                    }
                }
            }
        }
        if (ToolsUtil.isNotNull(rules)) {//以下处理执行插件
            resultMap.put("sqlKeyId", rules);
            String evelName = StrUtil.doNull(String.valueOf(params.get("evelName")),"beforMethodKey");//方法拦截方式,前拦或后拦
            resultMap.put(evelName, rules);
        } else {
            resultMap.put("sqlKeyId", "sqlKeyId");
        }
        //返回值名称,T:实体.属性名 或 F:属性名
        if ("T".equalsIgnoreCase(String.valueOf(params.get("resultName")))) {
            resultMap.put("_resultType", "T");
        }
        return resultMap;
    }

    /**
     * 判断是否是json结构
     */
    private static String buildParams(JSONObject params,String datasource,String modelType,Map<String, Object> resultMap,Map reqParams){
        StringBuilder sb = new StringBuilder();
        String cond = StrUtil.isNull(params.getString("ref")) ? "" : " "+params.getString("ref")+" ";
        String key = params.getString("key");
        String value = params.getString("val");
        JSONArray group = params.getJSONArray("sub");
        if(StrUtil.isNotNull(key)){
            String jud = params.getString("jud");
            boolean mark = modelType.indexOf(",") > -1;
            if(value.startsWith("[") && value.endsWith("]")){//以[xxx]为值
                if(!modelType.startsWith("s") || key.indexOf("wj_") !=-1) {
                    resultMap.put(key, value);
                    String exerules = String.valueOf(resultMap.get("exe_rules"));
                    if (StrUtil.isNull(exerules)) {
                        exerules = key + ":" + value;
                    } else {
                        exerules = exerules + "," + key + ":" + value;
                    }
                    resultMap.put("exe_rules", exerules);
                } else {
                    value = value.replace("[", "").replace("]", "");
                    String keystr[] = key.split("\\.");
                    String tabName = StringUtil.upperCharToUnderLine(keystr[0]);
                    Map<String, String> tableMap = getTableMap(tabName, datasource);
                    String cloumn = (mark ? keystr[0]+"." : "")+StringUtil.upperCharToUnderLine(keystr[1]);
                    sb.append(sqlWhere(cond, cloumn,value,tableMap.get(keystr[1]),jud,reqParams));
                }
            } else {
                String keystr[] = key.split("\\.");
                String tabName = StringUtil.upperCharToUnderLine(keystr[0]);
                Map<String, String> tableMap = getTableMap(tabName, datasource);
                String cloumn = (mark ? keystr[0]+"." : "")+StringUtil.upperCharToUnderLine(keystr[1]);
                sb.append(sqlWhere(cond,cloumn,value,tableMap.get(keystr[1]),jud,reqParams));
            }
        } else {
            if(!group.isEmpty()){
                StringBuilder stb = new StringBuilder(" "+cond+" (");
                for(int i=0;i<group.size();i++){
                    JSONObject obj = group.getJSONObject(i);
                    stb.append(buildParams(obj,datasource,modelType,resultMap,reqParams));
                }
                stb.append(")");
                sb.append(stb.toString());
            }
        }
        return sb.toString();
    }

    /**
     * 获取表字段信息
     */
    private static Map<String, String> getTableMap(String tableName, String sysName) {
        sysName = StrUtil.doNull(sysName, "plateform");
        String sortCode = tableName.substring(tableName.indexOf('_') + 1);
        Map<String, String> resultMap = (Map) LoadCacheFactory.getInstance().getCacheManager("")
                .getCacheObjectByKey(MessageUtil.getTableCacheKey(sortCode, sysName, "_tableMaps"));
        if (null == resultMap) {
            resultMap = new HashMap<String, String>(1);
        }
        return resultMap;
    }
//
    private static String sqlWhere(String cond, String column, String value, String dataType, String operator, Map reqParams) {
        operator = StrUtil.doNull(operator,"=");
        if(value.startsWith("{") && value.endsWith("}")){
            String val = value.replace("{","").replace("}","");
            value = String.valueOf(reqParams.get(val));
            reqParams.remove(val);
        }
        if (StrUtil.isNull(value)) {
            return "";
        }
        StringBuilder sql = new StringBuilder(cond+ " ");
        if("eq".equals(operator)){
            operator = "=";
            value = value.substring(0, value.indexOf('.')) + StringUtil.upperCharToUnderLine(value.substring(value.indexOf('.')));
            sql.append(column + " " + operator + value);
            return sql.toString();
        }
        if ("1".equals(dataType) || "2".equals(dataType) || "3".equals(dataType)) {
            if(operator.equals("in") || operator.equals("not in")){
                value = " (" + StrUtil.strArrayToStr(value.split(","), ",", "") + ")";
            } else if(operator.startsWith("is")){
                value = "";
            }
            sql.append(column + " " +operator + value);
        } else {
            if(operator.equals("like")){
                value = "'%"+value+"%'";
                sql.append(column + " " + operator + value);
            } else if(operator.equals("in") || operator.equals("not in")){
                value = " (" + StrUtil.strArrayToStr(value.split(","), ",", "'") + ")";
                sql.append(column + " " + operator + value);
            } else if(operator.startsWith("is")){
                sql.append(column + " " + operator);
            } else {
                sql.append(column + " " + operator + "'"+value+"'");
            }
        }
        return sql.toString();
    }

    public static void main(String[] args) {
        Map params = new HashMap();
        params.put("pageName","riskrule-2020042840560524");
        params.put("formName","riskForm");
        params.put("modelTypes","s_rpStraRiskRel,s_rpStrategy");
        params.put("sysName","rpac");
        params.put("relation","[{\"ref\":\"and\",\"key\":\"uctActGive.actId\",\"jud\":\"eq\",\"val\":\"uctAct.actId\",\"typ\":\"item\",\"sub\":[]},{\"ref\":\"and\",\"key\":\"\",\"jud\":\"\",\"val\":\"\",\"typ\":\"group\",\"sub\":[{\"ref\":\"\",\"key\":\"\",\"jud\":\"\",\"val\":\"\",\"typ\":\"group\",\"sub\":[{\"ref\":\"\",\"key\":\"uctActGive.giveType\",\"jud\":\"=\",\"val\":\"user\",\"typ\":\"item\",\"sub\":[]},{\"ref\":\"and\",\"key\":\"uctActGive.roleId\",\"jud\":\"=\",\"val\":\"{uctActGive.w_userId}\",\"typ\":\"item\",\"sub\":[]}]},{\"ref\":\"or\",\"key\":\"\",\"jud\":\"\",\"val\":\"\",\"typ\":\"group\",\"sub\":[{\"ref\":\"\",\"key\":\"uctActGive.giveType\",\"jud\":\"=\",\"val\":\"role\",\"typ\":\"item\",\"sub\":[]},{\"ref\":\"and\",\"key\":\"uctActGive.roleId\",\"jud\":\"=\",\"val\":\"{uctActGive.w_roleId}\",\"typ\":\"item\",\"sub\":[]}]}]}]");
        params.put("rulesName","");
        params.put("resultColumn","");
        params.put("checkColumn","");
        Map params2 = new HashMap();
        params2.put("rpStrategy.w_createDate","ddddd");
        ParamsVo vo = new ParamsVo();
        vo.setParams(params2);

        Map result = IUSRequestParams.analyzeParams(params,vo.getParams());
        System.out.println(result);
        System.out.println("-------------------------------------");
        System.out.println(vo.getParams());
    }

}
